# 提供用户登录的ＱＱ网址
from django.conf import settings
import urllib.parse
import urllib.request
import logging
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer, BadData
import json

from oauth import constants
from oauth.exceptions import OAuthQQAPIError


logger = logging.getLogger('django')


class OAuthQQ(object):

    def __init__(self, client_id=None, redirect_uri=None, state=None, client_secret=None):
        self.client_id = client_id or settings.QQ_CLIENT_ID
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URI
        self.state = state or settings.QQ_STATE
        self.client_secret = client_secret or settings.QQ_CLIENT_SECRET

    def get_qq_login_url(self):
        """
        获取qq登录的网址
        :return: url网址
        """
        # QQ　文档指明的访问网址
        url = 'https://graph.qq.com/oauth2.0/authorize?'
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': self.state,
            'scope': 'get_user_info',

        }
        url += urllib.parse.urlencode(params)
        return url

    def get_access_token(self, code):
        # QQ　文档指明的访问网址
        url = 'https://graph.qq.com/oauth2.0/token?'

        params = {
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri,
        }
        url += urllib.parse.urlencode(params)

        #  发送请求
        try:
            resp = urllib.request.urlopen(url)
            resp_data = resp.read() # bytes
            resp_data = resp_data.decode()  # str
            # access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14
            # 解析  parse_qs 将qs查询字符串格式数据转换为python的字典
            resp_dict = urllib.parse.parse_qs(resp_data)
        except Exception as e:
            logger.error('请求QQ access_token异常')
            raise OAuthQQAPIError
        else:
            access_token = resp_dict.get('access_token')

            return access_token[0]
    @staticmethod
    def get_openid(access_token):
        url = 'https://graph.qq.com/oauth2.0/me?access_token=' + access_token
        # 借助ｕｒｌｏｐｅｎ服务器向ＱＱ服务器发送请求
        resp = urllib.request.urlopen(url)
        resp_data = resp.read().decode()
        try:
            # 返回的数据 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )\n;
            resp_data =resp_data[10:-4]   # 这里的resp_data　是ｊｓｏｎ数据，需要解析成字典
            data = json.loads(resp_data)
        except Exception:
            logger.error('请求QQ openid异常')
            raise OAuthQQAPIError
        else:
            open_id = data.get("openid", None)
            return open_id

    @staticmethod
    # 把open_id　进行加密返回给前端
    def generate_save_user_token(openid):

        # 创建TJWSSerializer对象
        serializer = TJWSSerializer(settings.SECRET_KEY, constants.BIND_USER_ACCESS_TOKEN_EXPIRES)
        # 转换数据
        token = serializer.dumps({'openid': openid})  # bytes  ,字典转ｊｓｏｎ
        return token.decode()

    @staticmethod
    # 将用户传过来的access_token进行验证
    def check_bind_user_access_token(access_token):
        serializer = TJWSSerializer(settings.SECRET_KEY, constants.BIND_USER_ACCESS_TOKEN_EXPIRES)
        try:
            data = serializer.loads(access_token)
        except BadData:
            return None
        else:
            return data['openid']




